from collections.abc import Iterable, Iterator

# 如果一个对象拥有__iter__方法，那么这个对象就是可迭代对象;
# 可迭代对象：字符串、列表、元组、集合。
# 不可迭代对象：整数、浮点数、布尔。
print(isinstance(123, Iterable))
print(isinstance('abc', Iterable))
print(isinstance([1, 2, 3], Iterable))
print(isinstance({'name': 'jueyi'}, Iterable))
print(isinstance(10, int))

# 如果可迭代对象拥有__next__方法，那么这个对象就是迭代器。
list1 = [1, 2, 3]
# list_iterator = iter(list1)
list_iterator = list1.__iter__()
print(list_iterator, isinstance(list_iterator, Iterator))
next_item = next(list_iterator)
print(next_item)
next_item = next(list_iterator)
print(next_item)
next_item = next(list_iterator)
print(next_item)
try:
    next_item = next(list_iterator)
except StopIteration:
    print('迭代结束')


# 自定义迭代器
class MyIterator(object):

    def __iter__(self):
        self.n = 0
        # 返回self表示实例对象本身是自己的迭代器对象
        return self

    def __next__(self):
        self.n += 1
        return self.n


test = MyIterator()
test.__iter__()
print(test.__next__())
print(test.__next__())
print(test.__next__())

# 生成器是一种特殊的迭代器。在python中，生成器是通过yield关键字实现的。
li = (i * 10 for i in range(3))
print(li, next(li), next(li), next(li))


# 生成器函数
# 普通函数返回值用return，生成器函数返回值用yield
# yield语句一次返回一个结果，在每一个结果中间，挂起函数，以便下次从它离开的地方继续执行。
def func():
    print('start')
    yield 1
    yield 2
    yield 3


fb = func()
print(fb)
print(next(fb))
print(next(fb))
print(next(fb))
